{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "7.5. AdaGrad算法.ipynb",
      "provenance": [],
      "include_colab_link": true
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "view-in-github",
        "colab_type": "text"
      },
      "source": [
        "<a href=\"https://colab.research.google.com/github/chongzicbo/Dive-into-Deep-Learning-tf.keras/blob/master/7.5.%20AdaGrad%E7%AE%97%E6%B3%95.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "UDBwmro6kXxB",
        "colab_type": "text"
      },
      "source": [
        "##7.5. AdaGrad算法\n",
        "在之前介绍过的优化算法中，目标函数自变量的每一个元素在相同时间步都使用同一个学习率来自我迭代。举个例子，假设目标函数为 $f $，自变量为一个二维向量 $[x_1, x_2]^\\top$ ，该向量中每一个元素在迭代时都使用相同的学习率。例如，在学习率为 $\\eta$的梯度下降中，元素 $x_1$ 和 $x_2$ 都使用相同的学习率 $\\eta$来自我迭代：\n",
        "$$\n",
        "x_1 \\leftarrow x_1 - \\eta \\frac{\\partial{f}}{\\partial{x_1}}, \\quad\n",
        "x_2 \\leftarrow x_2 - \\eta \\frac{\\partial{f}}{\\partial{x_2}}.\n",
        "$$\n",
        "\n",
        "在“动量法”一节里我们看到当 $x_1 $和 $x_2$ 的梯度值有较大差别时，需要选择足够小的学习率使得自变量在梯度值较大的维度上不发散。但这样会导致自变量在梯度值较小的维度上迭代过慢。动量法依赖指数加权移动平均使得自变量的更新方向更加一致，从而降低发散的可能。本节我们介绍AdaGrad算法，它根据自变量在每个维度的梯度值的大小来调整各个维度上的学习率，从而避免统一的学习率难以适应所有维度的问题 [1]。\n",
        "\n",
        "###7.5.1. 算法\n",
        "AdaGrad算法会使用一个小批量随机梯度 $g_t$ 按元素平方的累加变量 $s_t$ 。在时间步0，AdaGrad将 $s_0$ 中每个元素初始化为0。在时间步 $t$ ，首先将小批量随机梯度 $g_t$ 按元素平方后累加到变量 $s_t$ ：\n",
        "$$\n",
        "\\boldsymbol{s}_t \\leftarrow \\boldsymbol{s}_{t-1} + \\boldsymbol{g}_t \\odot \\boldsymbol{g}_t,\n",
        "$$\n",
        "其中$\\odot$ 是按元素相乘。接着，我们将目标函数自变量中每个元素的学习率通过按元素运算重新调整一下：\n",
        "$$\n",
        "\\boldsymbol{x}_t \\leftarrow \\boldsymbol{x}_{t-1} - \\frac{\\eta}{\\sqrt{\\boldsymbol{s}_t + \\epsilon}} \\odot \\boldsymbol{g}_t,\n",
        "$$\n",
        "其中 $\\eta$ 是学习率，$\\epsilon$是为了维持数值稳定性而添加的常数，如 $10^{-6}$ 。这里开方、除法和乘法的运算都是按元素运算的。这些按元素运算使得目标函数自变量中每个元素都分别拥有自己的学习率。\n",
        "###7.5.2. 特点\n",
        "需要强调的是，小批量随机梯度按元素平方的累加变量 $s_t$ 出现在学习率的分母项中。因此，如果目标函数有关自变量中某个元素的偏导数一直都较大，那么该元素的学习率将下降较快；反之，如果目标函数有关自变量中某个元素的偏导数一直都较小，那么该元素的学习率将下降较慢。然而，由于 $s_t$ 一直在累加按元素平方的梯度，自变量中每个元素的学习率在迭代过程中一直在降低（或不变）。所以，当学习率在迭代早期降得较快且当前解依然不佳时，AdaGrad算法在迭代后期由于学习率过小，可能较难找到一个有用的解。\n",
        "\n",
        "下面我们仍然以目标函数 $f(\\boldsymbol{x})=0.1x_1^2+2x_2^2$为例观察AdaGrad算法对自变量的迭代轨迹。我们实现AdaGrad算法并使用和上一节实验中相同的学习率0.4。可以看到，自变量的迭代轨迹较平滑。但由于 $s_t$ 的累加效果使学习率不断衰减，自变量在迭代后期的移动幅度较小。\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "zo56guW8Q6aN",
        "colab_type": "code",
        "outputId": "cd0c0cec-4521-4df4-a855-23045e0ffa29",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 64
        }
      },
      "source": [
        "%matplotlib inline\n",
        "import math\n",
        "import tensorflow as tf\n",
        "import numpy as np\n",
        "from IPython import display\n",
        "import matplotlib.pyplot as plt\n",
        "from tensorflow import keras\n",
        "from tensorflow.keras import losses\n",
        "from tensorflow.data import Dataset\n",
        "import time"
      ],
      "execution_count": 0,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "text/html": [
              "<p style=\"color: red;\">\n",
              "The default version of TensorFlow in Colab will soon switch to TensorFlow 2.x.<br>\n",
              "We recommend you <a href=\"https://www.tensorflow.org/guide/migrate\" target=\"_blank\">upgrade</a> now \n",
              "or ensure your notebook will continue to use TensorFlow 1.x via the <code>%tensorflow_version 1.x</code> magic:\n",
              "<a href=\"https://colab.research.google.com/notebooks/tensorflow_version.ipynb\" target=\"_blank\">more info</a>.</p>\n"
            ],
            "text/plain": [
              "<IPython.core.display.HTML object>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "sQEP887vRAhw",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "tf.enable_eager_execution()"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "G6jI4CcjRDDI",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "def adagrad(x1,x2,s1,s2):\n",
        "  g1,g2,eps=0.2*x1,4*x2,1e-6\n",
        "  s1+=g1**2\n",
        "  s2+=g2**2\n",
        "  x1-=eta/math.sqrt(s1+eps)*g1\n",
        "  x2-=eta/math.sqrt(s2+eps)*g2\n",
        "  return x1,x2,s1,s2\n",
        "\n",
        "def f_2d(x1,x2):\n",
        "  return 0.1*x1**2+2*x2**2"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "qxbIjl7ER3mA",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "def show_trace_2d(f,results):\n",
        "  plt.plot(*zip(*results),'-o',color='#ff7f0e')\n",
        "  x1,x2=np.meshgrid(np.arange(-5.5,1.0,0.1),np.arange(-3.0,1.0,0.1))\n",
        "  plt.contour(x1,x2,f(x1,x2),colors='#1f77b4')\n",
        "  plt.xlabel('x1')\n",
        "  plt.ylabel('x2')\n",
        "\n",
        "def train_2d(trainer):\n",
        "  x1,x2,s1,s2=-5,-2,0,0 #s1,s2是自变量状态,本章后续几节会使用\n",
        "  results=[(x1,x2)]\n",
        "  for i in range(20):\n",
        "    x1,x2,s1,s2=trainer(x1,x2,s1,s2)\n",
        "    results.append((x1,x2))\n",
        "  print('epoch %d,x1 %f,x2 %f'%(i+1,x1,x2))\n",
        "  return results  "
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "21odGo7cRwP1",
        "colab_type": "code",
        "outputId": "0c8b8696-e8bb-4be2-b70f-10528a46a697",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 297
        }
      },
      "source": [
        "eta=0.4\n",
        "show_trace_2d(f_2d,train_2d(adagrad))"
      ],
      "execution_count": 0,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "epoch 20,x1 -2.382563,x2 -0.158591\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\nQM8JjuR1AAAAAElFTkSuQmCC\n",
            "text/plain": [
              "<Figure size 432x288 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "nSHOGG-AlpGx",
        "colab_type": "text"
      },
      "source": [
        "下面将学习率增大到2。可以看到自变量更为迅速地逼近了最优解。"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "h9lRu2e6SBlf",
        "colab_type": "code",
        "outputId": "389611ee-96ba-4bbb-cf34-8c7ba8b6b04e",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 297
        }
      },
      "source": [
        "eta=2\n",
        "show_trace_2d(f_2d,train_2d(adagrad))"
      ],
      "execution_count": 0,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "epoch 20,x1 -0.002295,x2 -0.000000\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\nF68abEMIBIvyAAAAAElFTkSuQmCC\n",
            "text/plain": [
              "<Figure size 432x288 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "dEB4bhr1lr2J",
        "colab_type": "text"
      },
      "source": [
        "###7.5.3. 从零开始实现\n",
        "同动量法一样，AdaGrad算法需要对每个自变量维护同它一样形状的状态变量。我们根据AdaGrad算法中的公式实现该算法。"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "5djlpehMSMTg",
        "colab_type": "code",
        "outputId": "04e82592-c680-4042-f9bd-1f812fe7e2b3",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 127
        }
      },
      "source": [
        "from google.colab import drive\n",
        "drive.mount('/content/drive')\n",
        "\n",
        "def get_data_ch7():\n",
        "  data=np.genfromtxt('/content/drive/My Drive/data/d2l-zh-tensoflow/airfoil_self_noise.dat',delimiter='\\t')\n",
        "  data=(data-data.mean(axis=0))/data.std(axis=0)\n",
        "  return tf.constant(data[:1500,:-1]),tf.constant(data[:1500,-1])\n",
        "\n",
        "features,labels=get_data_ch7()  "
      ],
      "execution_count": 0,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Go to this URL in a browser: https://accounts.google.com/o/oauth2/auth?client_id=947318989803-6bn6qk8qdgf4n4g3pfee6491hc0brc4i.apps.googleusercontent.com&redirect_uri=urn%3aietf%3awg%3aoauth%3a2.0%3aoob&response_type=code&scope=email%20https%3a%2f%2fwww.googleapis.com%2fauth%2fdocs.test%20https%3a%2f%2fwww.googleapis.com%2fauth%2fdrive%20https%3a%2f%2fwww.googleapis.com%2fauth%2fdrive.photos.readonly%20https%3a%2f%2fwww.googleapis.com%2fauth%2fpeopleapi.readonly\n",
            "\n",
            "Enter your authorization code:\n",
            "··········\n",
            "Mounted at /content/drive\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "seKGfl8xSS3H",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "def init_adagrad_states():\n",
        "  s_w=tf.Variable(tf.zeros((features.shape[1],1),dtype=tf.double))\n",
        "  s_b=tf.Variable(tf.zeros(1,dtype=tf.double))\n",
        "  return (s_w,s_b)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "Xk-xzi1QSy5s",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "def adagrad(params,states,hyperparams,loss,t):\n",
        "  eps=1e-6\n",
        "  for p,s in zip(params,states):\n",
        "    dl_dp=t.gradient(loss,p)\n",
        "    s.assign_add(tf.square(dl_dp))\n",
        "    p.assign_sub(hyperparams['lr']*dl_dp/tf.sqrt(s+eps))"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "IulVQmuXTsne",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "def train_ch7(trainer_fn,states,hyperparams,features,labels,batch_size=10,num_epochs=2):\n",
        "  net,loss=linreg,squared_loss\n",
        "  w=tf.Variable(tf.random.normal(stddev=0.01,shape=(features.shape[1],1),dtype=tf.double))\n",
        "  b=tf.Variable(tf.zeros(1,dtype=tf.double))\n",
        "\n",
        "  def eval_loss():\n",
        "    return tf.reduce_mean(loss(net(features,w,b),labels)).numpy()\n",
        "\n",
        "  ls=[eval_loss()]\n",
        "\n",
        "  data_iter=Dataset.from_tensor_slices((features,labels)).shuffle(buffer_size=1000).batch(batch_size)\n",
        "\n",
        "  for _ in range(num_epochs):\n",
        "    start=time.time()\n",
        "    for batch_i,(X,y) in enumerate(data_iter):\n",
        "      with tf.GradientTape(persistent=True) as t:\n",
        "        t.watch([w,b])\n",
        "        l=tf.reduce_mean(loss(net(X,w,b),y)) #使用平均损失\n",
        "\n",
        "      trainer_fn([w,b],states,hyperparams,l,t) #迭代模型参数\n",
        "\n",
        "      if(batch_i+1)*batch_size %100==0:\n",
        "        ls.append(eval_loss()) #每100个样本记录下当前训练误差\n",
        "  # 打印结果和作图\n",
        "  print('loss: %f, %f sec per epoch' % (ls[-1], time.time() - start))\n",
        "  set_figsize()\n",
        "  plt.plot(np.linspace(0, num_epochs, len(ls)), ls)\n",
        "  plt.xlabel('epoch')\n",
        "  plt.ylabel('loss')  "
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "FBHKfMylUK4Z",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "def use_svg_display():\n",
        "  #用矢量图显示\n",
        "  display.set_matplotlib_formats('svg')\n",
        "def set_figsize(figsize=(3.5,2.5)):\n",
        "  use_svg_display()\n",
        "  #设置图的尺寸\n",
        "  plt.rcParams['figure.figsize']=figsize\n",
        "  \n",
        "  \n",
        "def linreg(X,w,b):\n",
        "  return tf.matmul(X,w)+b \n",
        "  \n",
        "def squared_loss(y_hat,y):\n",
        "  return (y_hat-tf.reshape(y,shape=y_hat.shape))**2/2  "
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "LMjzQqcrT9m1",
        "colab_type": "code",
        "outputId": "aa9ecd03-e2ca-4fa3-8dc1-630879c8f4c3",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 279
        }
      },
      "source": [
        "train_ch7(adagrad,init_adagrad_states(),{'lr':0.1},features,labels)"
      ],
      "execution_count": 0,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "loss: 0.242379, 0.453403 sec per epoch\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "<Figure size 252x180 with 1 Axes>"
            ],
            "image/svg+xml": "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n  \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n<!-- Created with matplotlib (https://matplotlib.org/) -->\n<svg height=\"180.835349pt\" version=\"1.1\" viewBox=\"0 0 252.64375 180.835349\" width=\"252.64375pt\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n <defs>\n  <style type=\"text/css\">\n*{stroke-linecap:butt;stroke-linejoin:round;}\n  </style>\n </defs>\n <g id=\"figure_1\">\n  <g id=\"patch_1\">\n   <path d=\"M 0 180.835349 \nL 252.64375 180.835349 \nL 252.64375 0 \nL 0 0 \nz\n\" style=\"fill:none;\"/>\n  </g>\n  <g id=\"axes_1\">\n   <g id=\"patch_2\">\n    <path d=\"M 50.14375 143.279099 \nL 245.44375 143.279099 \nL 245.44375 7.379099 \nL 50.14375 7.379099 \nz\n\" style=\"fill:#ffffff;\"/>\n   </g>\n   <g id=\"matplotlib.axis_1\">\n    <g id=\"xtick_1\">\n     <g id=\"line2d_1\">\n      <defs>\n       <path d=\"M 0 0 \nL 0 3.5 \n\" id=\"m74447f8727\" style=\"stroke:#000000;stroke-width:0.8;\"/>\n      </defs>\n      <g>\n       <use style=\"stroke:#000000;stroke-width:0.8;\" x=\"59.021023\" xlink:href=\"#m74447f8727\" y=\"143.279099\"/>\n      </g>\n     </g>\n     <g id=\"text_1\">\n      <!-- 0.0 -->\n      <defs>\n       <path d=\"M 31.78125 66.40625 \nQ 24.171875 66.40625 20.328125 58.90625 \nQ 16.5 51.421875 16.5 36.375 \nQ 16.5 21.390625 20.328125 13.890625 \nQ 24.171875 6.390625 31.78125 6.390625 \nQ 39.453125 6.390625 43.28125 13.890625 \nQ 47.125 21.390625 47.125 36.375 \nQ 47.125 51.421875 43.28125 58.90625 \nQ 39.453125 66.40625 31.78125 66.40625 \nz\nM 31.78125 74.21875 \nQ 44.046875 74.21875 50.515625 64.515625 \nQ 56.984375 54.828125 56.984375 36.375 \nQ 56.984375 17.96875 50.515625 8.265625 \nQ 44.046875 -1.421875 31.78125 -1.421875 \nQ 19.53125 -1.421875 13.0625 8.265625 \nQ 6.59375 17.96875 6.59375 36.375 \nQ 6.59375 54.828125 13.0625 64.515625 \nQ 19.53125 74.21875 31.78125 74.21875 \nz\n\" id=\"DejaVuSans-48\"/>\n       <path d=\"M 10.6875 12.40625 \nL 21 12.40625 \nL 21 0 \nL 10.6875 0 \nz\n\" id=\"DejaVuSans-46\"/>\n      </defs>\n      <g transform=\"translate(51.06946 157.877537)scale(0.1 -0.1)\">\n       <use xlink:href=\"#DejaVuSans-48\"/>\n       <use x=\"63.623047\" xlink:href=\"#DejaVuSans-46\"/>\n       <use x=\"95.410156\" xlink:href=\"#DejaVuSans-48\"/>\n      </g>\n     </g>\n    </g>\n    <g id=\"xtick_2\">\n     <g id=\"line2d_2\">\n      <g>\n       <use style=\"stroke:#000000;stroke-width:0.8;\" x=\"103.407386\" xlink:href=\"#m74447f8727\" y=\"143.279099\"/>\n      </g>\n     </g>\n     <g id=\"text_2\">\n      <!-- 0.5 -->\n      <defs>\n       <path d=\"M 10.796875 72.90625 \nL 49.515625 72.90625 \nL 49.515625 64.59375 \nL 19.828125 64.59375 \nL 19.828125 46.734375 \nQ 21.96875 47.46875 24.109375 47.828125 \nQ 26.265625 48.1875 28.421875 48.1875 \nQ 40.625 48.1875 47.75 41.5 \nQ 54.890625 34.8125 54.890625 23.390625 \nQ 54.890625 11.625 47.5625 5.09375 \nQ 40.234375 -1.421875 26.90625 -1.421875 \nQ 22.3125 -1.421875 17.546875 -0.640625 \nQ 12.796875 0.140625 7.71875 1.703125 \nL 7.71875 11.625 \nQ 12.109375 9.234375 16.796875 8.0625 \nQ 21.484375 6.890625 26.703125 6.890625 \nQ 35.15625 6.890625 40.078125 11.328125 \nQ 45.015625 15.765625 45.015625 23.390625 \nQ 45.015625 31 40.078125 35.4375 \nQ 35.15625 39.890625 26.703125 39.890625 \nQ 22.75 39.890625 18.8125 39.015625 \nQ 14.890625 38.140625 10.796875 36.28125 \nz\n\" id=\"DejaVuSans-53\"/>\n      </defs>\n      <g transform=\"translate(95.455824 157.877537)scale(0.1 -0.1)\">\n       <use xlink:href=\"#DejaVuSans-48\"/>\n       <use x=\"63.623047\" xlink:href=\"#DejaVuSans-46\"/>\n       <use x=\"95.410156\" xlink:href=\"#DejaVuSans-53\"/>\n      </g>\n     </g>\n    </g>\n    <g id=\"xtick_3\">\n     <g id=\"line2d_3\">\n      <g>\n       <use style=\"stroke:#000000;stroke-width:0.8;\" x=\"147.79375\" xlink:href=\"#m74447f8727\" y=\"143.279099\"/>\n      </g>\n     </g>\n     <g id=\"text_3\">\n      <!-- 1.0 -->\n      <defs>\n       <path d=\"M 12.40625 8.296875 \nL 28.515625 8.296875 \nL 28.515625 63.921875 \nL 10.984375 60.40625 \nL 10.984375 69.390625 \nL 28.421875 72.90625 \nL 38.28125 72.90625 \nL 38.28125 8.296875 \nL 54.390625 8.296875 \nL 54.390625 0 \nL 12.40625 0 \nz\n\" id=\"DejaVuSans-49\"/>\n      </defs>\n      <g transform=\"translate(139.842187 157.877537)scale(0.1 -0.1)\">\n       <use xlink:href=\"#DejaVuSans-49\"/>\n       <use x=\"63.623047\" xlink:href=\"#DejaVuSans-46\"/>\n       <use x=\"95.410156\" xlink:href=\"#DejaVuSans-48\"/>\n      </g>\n     </g>\n    </g>\n    <g id=\"xtick_4\">\n     <g id=\"line2d_4\">\n      <g>\n       <use style=\"stroke:#000000;stroke-width:0.8;\" x=\"192.180114\" xlink:href=\"#m74447f8727\" y=\"143.279099\"/>\n      </g>\n     </g>\n     <g id=\"text_4\">\n      <!-- 1.5 -->\n      <g transform=\"translate(184.228551 157.877537)scale(0.1 -0.1)\">\n       <use xlink:href=\"#DejaVuSans-49\"/>\n       <use x=\"63.623047\" xlink:href=\"#DejaVuSans-46\"/>\n       <use x=\"95.410156\" xlink:href=\"#DejaVuSans-53\"/>\n      </g>\n     </g>\n    </g>\n    <g id=\"xtick_5\">\n     <g id=\"line2d_5\">\n      <g>\n       <use style=\"stroke:#000000;stroke-width:0.8;\" x=\"236.566477\" xlink:href=\"#m74447f8727\" y=\"143.279099\"/>\n      </g>\n     </g>\n     <g id=\"text_5\">\n      <!-- 2.0 -->\n      <defs>\n       <path d=\"M 19.1875 8.296875 \nL 53.609375 8.296875 \nL 53.609375 0 \nL 7.328125 0 \nL 7.328125 8.296875 \nQ 12.9375 14.109375 22.625 23.890625 \nQ 32.328125 33.6875 34.8125 36.53125 \nQ 39.546875 41.84375 41.421875 45.53125 \nQ 43.3125 49.21875 43.3125 52.78125 \nQ 43.3125 58.59375 39.234375 62.25 \nQ 35.15625 65.921875 28.609375 65.921875 \nQ 23.96875 65.921875 18.8125 64.3125 \nQ 13.671875 62.703125 7.8125 59.421875 \nL 7.8125 69.390625 \nQ 13.765625 71.78125 18.9375 73 \nQ 24.125 74.21875 28.421875 74.21875 \nQ 39.75 74.21875 46.484375 68.546875 \nQ 53.21875 62.890625 53.21875 53.421875 \nQ 53.21875 48.921875 51.53125 44.890625 \nQ 49.859375 40.875 45.40625 35.40625 \nQ 44.1875 33.984375 37.640625 27.21875 \nQ 31.109375 20.453125 19.1875 8.296875 \nz\n\" id=\"DejaVuSans-50\"/>\n      </defs>\n      <g transform=\"translate(228.614915 157.877537)scale(0.1 -0.1)\">\n       <use xlink:href=\"#DejaVuSans-50\"/>\n       <use x=\"63.623047\" xlink:href=\"#DejaVuSans-46\"/>\n       <use x=\"95.410156\" xlink:href=\"#DejaVuSans-48\"/>\n      </g>\n     </g>\n    </g>\n    <g id=\"text_6\">\n     <!-- epoch -->\n     <defs>\n      <path d=\"M 56.203125 29.59375 \nL 56.203125 25.203125 \nL 14.890625 25.203125 \nQ 15.484375 15.921875 20.484375 11.0625 \nQ 25.484375 6.203125 34.421875 6.203125 \nQ 39.59375 6.203125 44.453125 7.46875 \nQ 49.3125 8.734375 54.109375 11.28125 \nL 54.109375 2.78125 \nQ 49.265625 0.734375 44.1875 -0.34375 \nQ 39.109375 -1.421875 33.890625 -1.421875 \nQ 20.796875 -1.421875 13.15625 6.1875 \nQ 5.515625 13.8125 5.515625 26.8125 \nQ 5.515625 40.234375 12.765625 48.109375 \nQ 20.015625 56 32.328125 56 \nQ 43.359375 56 49.78125 48.890625 \nQ 56.203125 41.796875 56.203125 29.59375 \nz\nM 47.21875 32.234375 \nQ 47.125 39.59375 43.09375 43.984375 \nQ 39.0625 48.390625 32.421875 48.390625 \nQ 24.90625 48.390625 20.390625 44.140625 \nQ 15.875 39.890625 15.1875 32.171875 \nz\n\" id=\"DejaVuSans-101\"/>\n      <path d=\"M 18.109375 8.203125 \nL 18.109375 -20.796875 \nL 9.078125 -20.796875 \nL 9.078125 54.6875 \nL 18.109375 54.6875 \nL 18.109375 46.390625 \nQ 20.953125 51.265625 25.265625 53.625 \nQ 29.59375 56 35.59375 56 \nQ 45.5625 56 51.78125 48.09375 \nQ 58.015625 40.1875 58.015625 27.296875 \nQ 58.015625 14.40625 51.78125 6.484375 \nQ 45.5625 -1.421875 35.59375 -1.421875 \nQ 29.59375 -1.421875 25.265625 0.953125 \nQ 20.953125 3.328125 18.109375 8.203125 \nz\nM 48.6875 27.296875 \nQ 48.6875 37.203125 44.609375 42.84375 \nQ 40.53125 48.484375 33.40625 48.484375 \nQ 26.265625 48.484375 22.1875 42.84375 \nQ 18.109375 37.203125 18.109375 27.296875 \nQ 18.109375 17.390625 22.1875 11.75 \nQ 26.265625 6.109375 33.40625 6.109375 \nQ 40.53125 6.109375 44.609375 11.75 \nQ 48.6875 17.390625 48.6875 27.296875 \nz\n\" id=\"DejaVuSans-112\"/>\n      <path d=\"M 30.609375 48.390625 \nQ 23.390625 48.390625 19.1875 42.75 \nQ 14.984375 37.109375 14.984375 27.296875 \nQ 14.984375 17.484375 19.15625 11.84375 \nQ 23.34375 6.203125 30.609375 6.203125 \nQ 37.796875 6.203125 41.984375 11.859375 \nQ 46.1875 17.53125 46.1875 27.296875 \nQ 46.1875 37.015625 41.984375 42.703125 \nQ 37.796875 48.390625 30.609375 48.390625 \nz\nM 30.609375 56 \nQ 42.328125 56 49.015625 48.375 \nQ 55.71875 40.765625 55.71875 27.296875 \nQ 55.71875 13.875 49.015625 6.21875 \nQ 42.328125 -1.421875 30.609375 -1.421875 \nQ 18.84375 -1.421875 12.171875 6.21875 \nQ 5.515625 13.875 5.515625 27.296875 \nQ 5.515625 40.765625 12.171875 48.375 \nQ 18.84375 56 30.609375 56 \nz\n\" id=\"DejaVuSans-111\"/>\n      <path d=\"M 48.78125 52.59375 \nL 48.78125 44.1875 \nQ 44.96875 46.296875 41.140625 47.34375 \nQ 37.3125 48.390625 33.40625 48.390625 \nQ 24.65625 48.390625 19.8125 42.84375 \nQ 14.984375 37.3125 14.984375 27.296875 \nQ 14.984375 17.28125 19.8125 11.734375 \nQ 24.65625 6.203125 33.40625 6.203125 \nQ 37.3125 6.203125 41.140625 7.25 \nQ 44.96875 8.296875 48.78125 10.40625 \nL 48.78125 2.09375 \nQ 45.015625 0.34375 40.984375 -0.53125 \nQ 36.96875 -1.421875 32.421875 -1.421875 \nQ 20.0625 -1.421875 12.78125 6.34375 \nQ 5.515625 14.109375 5.515625 27.296875 \nQ 5.515625 40.671875 12.859375 48.328125 \nQ 20.21875 56 33.015625 56 \nQ 37.15625 56 41.109375 55.140625 \nQ 45.0625 54.296875 48.78125 52.59375 \nz\n\" id=\"DejaVuSans-99\"/>\n      <path d=\"M 54.890625 33.015625 \nL 54.890625 0 \nL 45.90625 0 \nL 45.90625 32.71875 \nQ 45.90625 40.484375 42.875 44.328125 \nQ 39.84375 48.1875 33.796875 48.1875 \nQ 26.515625 48.1875 22.3125 43.546875 \nQ 18.109375 38.921875 18.109375 30.90625 \nL 18.109375 0 \nL 9.078125 0 \nL 9.078125 75.984375 \nL 18.109375 75.984375 \nL 18.109375 46.1875 \nQ 21.34375 51.125 25.703125 53.5625 \nQ 30.078125 56 35.796875 56 \nQ 45.21875 56 50.046875 50.171875 \nQ 54.890625 44.34375 54.890625 33.015625 \nz\n\" id=\"DejaVuSans-104\"/>\n     </defs>\n     <g transform=\"translate(132.565625 171.555662)scale(0.1 -0.1)\">\n      <use xlink:href=\"#DejaVuSans-101\"/>\n      <use x=\"61.523438\" xlink:href=\"#DejaVuSans-112\"/>\n      <use x=\"125\" xlink:href=\"#DejaVuSans-111\"/>\n      <use x=\"186.181641\" xlink:href=\"#DejaVuSans-99\"/>\n      <use x=\"241.162109\" xlink:href=\"#DejaVuSans-104\"/>\n     </g>\n    </g>\n   </g>\n   <g id=\"matplotlib.axis_2\">\n    <g id=\"ytick_1\">\n     <g id=\"line2d_6\">\n      <defs>\n       <path d=\"M 0 0 \nL -3.5 0 \n\" id=\"m822eee81bc\" style=\"stroke:#000000;stroke-width:0.8;\"/>\n      </defs>\n      <g>\n       <use style=\"stroke:#000000;stroke-width:0.8;\" x=\"50.14375\" xlink:href=\"#m822eee81bc\" y=\"133.229759\"/>\n      </g>\n     </g>\n     <g id=\"text_7\">\n      <!-- 0.25 -->\n      <g transform=\"translate(20.878125 137.028978)scale(0.1 -0.1)\">\n       <use xlink:href=\"#DejaVuSans-48\"/>\n       <use x=\"63.623047\" xlink:href=\"#DejaVuSans-46\"/>\n       <use x=\"95.410156\" xlink:href=\"#DejaVuSans-50\"/>\n       <use x=\"159.033203\" xlink:href=\"#DejaVuSans-53\"/>\n      </g>\n     </g>\n    </g>\n    <g id=\"ytick_2\">\n     <g id=\"line2d_7\">\n      <g>\n       <use style=\"stroke:#000000;stroke-width:0.8;\" x=\"50.14375\" xlink:href=\"#m822eee81bc\" y=\"108.783651\"/>\n      </g>\n     </g>\n     <g id=\"text_8\">\n      <!-- 0.30 -->\n      <defs>\n       <path d=\"M 40.578125 39.3125 \nQ 47.65625 37.796875 51.625 33 \nQ 55.609375 28.21875 55.609375 21.1875 \nQ 55.609375 10.40625 48.1875 4.484375 \nQ 40.765625 -1.421875 27.09375 -1.421875 \nQ 22.515625 -1.421875 17.65625 -0.515625 \nQ 12.796875 0.390625 7.625 2.203125 \nL 7.625 11.71875 \nQ 11.71875 9.328125 16.59375 8.109375 \nQ 21.484375 6.890625 26.8125 6.890625 \nQ 36.078125 6.890625 40.9375 10.546875 \nQ 45.796875 14.203125 45.796875 21.1875 \nQ 45.796875 27.640625 41.28125 31.265625 \nQ 36.765625 34.90625 28.71875 34.90625 \nL 20.21875 34.90625 \nL 20.21875 43.015625 \nL 29.109375 43.015625 \nQ 36.375 43.015625 40.234375 45.921875 \nQ 44.09375 48.828125 44.09375 54.296875 \nQ 44.09375 59.90625 40.109375 62.90625 \nQ 36.140625 65.921875 28.71875 65.921875 \nQ 24.65625 65.921875 20.015625 65.03125 \nQ 15.375 64.15625 9.8125 62.3125 \nL 9.8125 71.09375 \nQ 15.4375 72.65625 20.34375 73.4375 \nQ 25.25 74.21875 29.59375 74.21875 \nQ 40.828125 74.21875 47.359375 69.109375 \nQ 53.90625 64.015625 53.90625 55.328125 \nQ 53.90625 49.265625 50.4375 45.09375 \nQ 46.96875 40.921875 40.578125 39.3125 \nz\n\" id=\"DejaVuSans-51\"/>\n      </defs>\n      <g transform=\"translate(20.878125 112.58287)scale(0.1 -0.1)\">\n       <use xlink:href=\"#DejaVuSans-48\"/>\n       <use x=\"63.623047\" xlink:href=\"#DejaVuSans-46\"/>\n       <use x=\"95.410156\" xlink:href=\"#DejaVuSans-51\"/>\n       <use x=\"159.033203\" xlink:href=\"#DejaVuSans-48\"/>\n      </g>\n     </g>\n    </g>\n    <g id=\"ytick_3\">\n     <g id=\"line2d_8\">\n      <g>\n       <use style=\"stroke:#000000;stroke-width:0.8;\" x=\"50.14375\" xlink:href=\"#m822eee81bc\" y=\"84.337543\"/>\n      </g>\n     </g>\n     <g id=\"text_9\">\n      <!-- 0.35 -->\n      <g transform=\"translate(20.878125 88.136762)scale(0.1 -0.1)\">\n       <use xlink:href=\"#DejaVuSans-48\"/>\n       <use x=\"63.623047\" xlink:href=\"#DejaVuSans-46\"/>\n       <use x=\"95.410156\" xlink:href=\"#DejaVuSans-51\"/>\n       <use x=\"159.033203\" xlink:href=\"#DejaVuSans-53\"/>\n      </g>\n     </g>\n    </g>\n    <g id=\"ytick_4\">\n     <g id=\"line2d_9\">\n      <g>\n       <use style=\"stroke:#000000;stroke-width:0.8;\" x=\"50.14375\" xlink:href=\"#m822eee81bc\" y=\"59.891435\"/>\n      </g>\n     </g>\n     <g id=\"text_10\">\n      <!-- 0.40 -->\n      <defs>\n       <path d=\"M 37.796875 64.3125 \nL 12.890625 25.390625 \nL 37.796875 25.390625 \nz\nM 35.203125 72.90625 \nL 47.609375 72.90625 \nL 47.609375 25.390625 \nL 58.015625 25.390625 \nL 58.015625 17.1875 \nL 47.609375 17.1875 \nL 47.609375 0 \nL 37.796875 0 \nL 37.796875 17.1875 \nL 4.890625 17.1875 \nL 4.890625 26.703125 \nz\n\" id=\"DejaVuSans-52\"/>\n      </defs>\n      <g transform=\"translate(20.878125 63.690654)scale(0.1 -0.1)\">\n       <use xlink:href=\"#DejaVuSans-48\"/>\n       <use x=\"63.623047\" xlink:href=\"#DejaVuSans-46\"/>\n       <use x=\"95.410156\" xlink:href=\"#DejaVuSans-52\"/>\n       <use x=\"159.033203\" xlink:href=\"#DejaVuSans-48\"/>\n      </g>\n     </g>\n    </g>\n    <g id=\"ytick_5\">\n     <g id=\"line2d_10\">\n      <g>\n       <use style=\"stroke:#000000;stroke-width:0.8;\" x=\"50.14375\" xlink:href=\"#m822eee81bc\" y=\"35.445327\"/>\n      </g>\n     </g>\n     <g id=\"text_11\">\n      <!-- 0.45 -->\n      <g transform=\"translate(20.878125 39.244546)scale(0.1 -0.1)\">\n       <use xlink:href=\"#DejaVuSans-48\"/>\n       <use x=\"63.623047\" xlink:href=\"#DejaVuSans-46\"/>\n       <use x=\"95.410156\" xlink:href=\"#DejaVuSans-52\"/>\n       <use x=\"159.033203\" xlink:href=\"#DejaVuSans-53\"/>\n      </g>\n     </g>\n    </g>\n    <g id=\"ytick_6\">\n     <g id=\"line2d_11\">\n      <g>\n       <use style=\"stroke:#000000;stroke-width:0.8;\" x=\"50.14375\" xlink:href=\"#m822eee81bc\" y=\"10.999219\"/>\n      </g>\n     </g>\n     <g id=\"text_12\">\n      <!-- 0.50 -->\n      <g transform=\"translate(20.878125 14.798438)scale(0.1 -0.1)\">\n       <use xlink:href=\"#DejaVuSans-48\"/>\n       <use x=\"63.623047\" xlink:href=\"#DejaVuSans-46\"/>\n       <use x=\"95.410156\" xlink:href=\"#DejaVuSans-53\"/>\n       <use x=\"159.033203\" xlink:href=\"#DejaVuSans-48\"/>\n      </g>\n     </g>\n    </g>\n    <g id=\"text_13\">\n     <!-- loss -->\n     <defs>\n      <path d=\"M 9.421875 75.984375 \nL 18.40625 75.984375 \nL 18.40625 0 \nL 9.421875 0 \nz\n\" id=\"DejaVuSans-108\"/>\n      <path d=\"M 44.28125 53.078125 \nL 44.28125 44.578125 \nQ 40.484375 46.53125 36.375 47.5 \nQ 32.28125 48.484375 27.875 48.484375 \nQ 21.1875 48.484375 17.84375 46.4375 \nQ 14.5 44.390625 14.5 40.28125 \nQ 14.5 37.15625 16.890625 35.375 \nQ 19.28125 33.59375 26.515625 31.984375 \nL 29.59375 31.296875 \nQ 39.15625 29.25 43.1875 25.515625 \nQ 47.21875 21.78125 47.21875 15.09375 \nQ 47.21875 7.46875 41.1875 3.015625 \nQ 35.15625 -1.421875 24.609375 -1.421875 \nQ 20.21875 -1.421875 15.453125 -0.5625 \nQ 10.6875 0.296875 5.421875 2 \nL 5.421875 11.28125 \nQ 10.40625 8.6875 15.234375 7.390625 \nQ 20.0625 6.109375 24.8125 6.109375 \nQ 31.15625 6.109375 34.5625 8.28125 \nQ 37.984375 10.453125 37.984375 14.40625 \nQ 37.984375 18.0625 35.515625 20.015625 \nQ 33.0625 21.96875 24.703125 23.78125 \nL 21.578125 24.515625 \nQ 13.234375 26.265625 9.515625 29.90625 \nQ 5.8125 33.546875 5.8125 39.890625 \nQ 5.8125 47.609375 11.28125 51.796875 \nQ 16.75 56 26.8125 56 \nQ 31.78125 56 36.171875 55.265625 \nQ 40.578125 54.546875 44.28125 53.078125 \nz\n\" id=\"DejaVuSans-115\"/>\n     </defs>\n     <g transform=\"translate(14.798437 84.986912)rotate(-90)scale(0.1 -0.1)\">\n      <use xlink:href=\"#DejaVuSans-108\"/>\n      <use x=\"27.783203\" xlink:href=\"#DejaVuSans-111\"/>\n      <use x=\"88.964844\" xlink:href=\"#DejaVuSans-115\"/>\n      <use x=\"141.064453\" xlink:href=\"#DejaVuSans-115\"/>\n     </g>\n    </g>\n   </g>\n   <g id=\"line2d_12\">\n    <path clip-path=\"url(#pd8d4145e7d)\" d=\"M 59.021023 13.556372 \nL 64.939205 118.197116 \nL 70.857386 130.891487 \nL 76.775568 127.518346 \nL 82.69375 129.078029 \nL 88.611932 132.198092 \nL 94.530114 131.386204 \nL 100.448295 135.278342 \nL 106.366477 136.46139 \nL 112.284659 136.692236 \nL 118.202841 136.427888 \nL 124.121023 134.621379 \nL 130.039205 136.389919 \nL 135.957386 136.154156 \nL 141.875568 135.19392 \nL 147.79375 136.784408 \nL 153.711932 136.655829 \nL 159.630114 137.081546 \nL 165.548295 135.668901 \nL 171.466477 134.302566 \nL 177.384659 134.719212 \nL 183.302841 135.889902 \nL 189.221023 136.640713 \nL 195.139205 137.101826 \nL 201.057386 136.976826 \nL 206.975568 137.021037 \nL 212.89375 135.614216 \nL 218.811932 136.797369 \nL 224.730114 136.800163 \nL 230.648295 136.067733 \nL 236.566477 136.955731 \n\" style=\"fill:none;stroke:#1f77b4;stroke-linecap:square;stroke-width:1.5;\"/>\n   </g>\n   <g id=\"patch_3\">\n    <path d=\"M 50.14375 143.279099 \nL 50.14375 7.379099 \n\" style=\"fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;\"/>\n   </g>\n   <g id=\"patch_4\">\n    <path d=\"M 245.44375 143.279099 \nL 245.44375 7.379099 \n\" style=\"fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;\"/>\n   </g>\n   <g id=\"patch_5\">\n    <path d=\"M 50.14375 143.279099 \nL 245.44375 143.279099 \n\" style=\"fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;\"/>\n   </g>\n   <g id=\"patch_6\">\n    <path d=\"M 50.14375 7.379099 \nL 245.44375 7.379099 \n\" style=\"fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;\"/>\n   </g>\n  </g>\n </g>\n <defs>\n  <clipPath id=\"pd8d4145e7d\">\n   <rect height=\"135.9\" width=\"195.3\" x=\"50.14375\" y=\"7.379099\"/>\n  </clipPath>\n </defs>\n</svg>\n"
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "bAgpiVlrlx3Y",
        "colab_type": "text"
      },
      "source": [
        "###7.5.4. 简洁实现"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "QoHHCTaMUFip",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "def train_keras_ch7(trainer_name,features,labels,batch_size=10,num_epochs=2):\n",
        "  net=keras.Sequential(keras.layers.Dense(1))\n",
        "  loss=losses.mean_squared_error\n",
        "  data_iter=Dataset.from_tensor_slices((features,labels)).shuffle(buffer_size=1000).batch(batch_size)\n",
        "  net.compile(optimizer=trainer_name,loss=loss,metrics=['mse'])\n",
        "  history=net.fit_generator(data_iter,epochs=num_epochs)\n",
        "  loss_ls=history.history['loss']\n",
        "  set_figsize()\n",
        "  plt.plot(np.linspace(0,num_epochs,len(loss_ls)),loss_ls)\n",
        "  plt.xlabel('epoch')\n",
        "  plt.ylabel('loss')\n",
        "  plt.show()\n",
        "  return history"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "7kgTYXJGURrI",
        "colab_type": "code",
        "outputId": "773ff80a-c33f-4fcd-875f-1720ec90de9d",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 1000
        }
      },
      "source": [
        "train_keras_ch7(keras.optimizers.Adagrad(learning_rate=0.1),features,labels,num_epochs=30)"
      ],
      "execution_count": 0,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Epoch 1/30\n",
            "150/150 [==============================] - 1s 6ms/step - loss: 1.2273 - mean_squared_error: 1.9098\n",
            "Epoch 2/30\n",
            "150/150 [==============================] - 1s 6ms/step - loss: 0.5878 - mean_squared_error: 0.6043\n",
            "Epoch 3/30\n",
            "150/150 [==============================] - 1s 6ms/step - loss: 0.5222 - mean_squared_error: 0.5181\n",
            "Epoch 4/30\n",
            "150/150 [==============================] - 1s 6ms/step - loss: 0.5024 - mean_squared_error: 0.4966\n",
            "Epoch 5/30\n",
            "150/150 [==============================] - 1s 6ms/step - loss: 0.4941 - mean_squared_error: 0.4884\n",
            "Epoch 6/30\n",
            "150/150 [==============================] - 1s 6ms/step - loss: 0.4903 - mean_squared_error: 0.4847\n",
            "Epoch 7/30\n",
            "150/150 [==============================] - 1s 6ms/step - loss: 0.4884 - mean_squared_error: 0.4829\n",
            "Epoch 8/30\n",
            "150/150 [==============================] - 1s 6ms/step - loss: 0.4873 - mean_squared_error: 0.4820\n",
            "Epoch 9/30\n",
            "150/150 [==============================] - 1s 6ms/step - loss: 0.4867 - mean_squared_error: 0.4814\n",
            "Epoch 10/30\n",
            "150/150 [==============================] - 1s 6ms/step - loss: 0.4864 - mean_squared_error: 0.4811\n",
            "Epoch 11/30\n",
            "150/150 [==============================] - 1s 6ms/step - loss: 0.4861 - mean_squared_error: 0.4809\n",
            "Epoch 12/30\n",
            "150/150 [==============================] - 1s 6ms/step - loss: 0.4860 - mean_squared_error: 0.4808\n",
            "Epoch 13/30\n",
            "150/150 [==============================] - 1s 6ms/step - loss: 0.4858 - mean_squared_error: 0.4806\n",
            "Epoch 14/30\n",
            "150/150 [==============================] - 1s 6ms/step - loss: 0.4858 - mean_squared_error: 0.4805\n",
            "Epoch 15/30\n",
            "150/150 [==============================] - 1s 6ms/step - loss: 0.4857 - mean_squared_error: 0.4805\n",
            "Epoch 16/30\n",
            "150/150 [==============================] - 1s 6ms/step - loss: 0.4856 - mean_squared_error: 0.4804\n",
            "Epoch 17/30\n",
            "150/150 [==============================] - 1s 6ms/step - loss: 0.4856 - mean_squared_error: 0.4803\n",
            "Epoch 18/30\n",
            "150/150 [==============================] - 1s 6ms/step - loss: 0.4855 - mean_squared_error: 0.4803\n",
            "Epoch 19/30\n",
            "150/150 [==============================] - 1s 6ms/step - loss: 0.4855 - mean_squared_error: 0.4802\n",
            "Epoch 20/30\n",
            "150/150 [==============================] - 1s 6ms/step - loss: 0.4854 - mean_squared_error: 0.4802\n",
            "Epoch 21/30\n",
            "150/150 [==============================] - 1s 6ms/step - loss: 0.4854 - mean_squared_error: 0.4801\n",
            "Epoch 22/30\n",
            "150/150 [==============================] - 1s 6ms/step - loss: 0.4853 - mean_squared_error: 0.4801\n",
            "Epoch 23/30\n",
            "150/150 [==============================] - 1s 6ms/step - loss: 0.4853 - mean_squared_error: 0.4800\n",
            "Epoch 24/30\n",
            "150/150 [==============================] - 1s 6ms/step - loss: 0.4853 - mean_squared_error: 0.4800\n",
            "Epoch 25/30\n",
            "150/150 [==============================] - 1s 6ms/step - loss: 0.4853 - mean_squared_error: 0.4800\n",
            "Epoch 26/30\n",
            "150/150 [==============================] - 1s 6ms/step - loss: 0.4852 - mean_squared_error: 0.4799\n",
            "Epoch 27/30\n",
            "150/150 [==============================] - 1s 6ms/step - loss: 0.4852 - mean_squared_error: 0.4799\n",
            "Epoch 28/30\n",
            "150/150 [==============================] - 1s 6ms/step - loss: 0.4852 - mean_squared_error: 0.4799\n",
            "Epoch 29/30\n",
            "150/150 [==============================] - 1s 6ms/step - loss: 0.4851 - mean_squared_error: 0.4798\n",
            "Epoch 30/30\n",
            "150/150 [==============================] - 1s 6ms/step - loss: 0.4851 - mean_squared_error: 0.4798\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "<Figure size 252x180 with 1 Axes>"
            ],
            "image/svg+xml": "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n  \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n<!-- Created with matplotlib (https://matplotlib.org/) -->\n<svg height=\"180.65625pt\" version=\"1.1\" viewBox=\"0 0 246.28125 180.65625\" width=\"246.28125pt\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n <defs>\n  <style type=\"text/css\">\n*{stroke-linecap:butt;stroke-linejoin:round;}\n  </style>\n </defs>\n <g id=\"figure_1\">\n  <g id=\"patch_1\">\n   <path d=\"M 0 180.65625 \nL 246.28125 180.65625 \nL 246.28125 0 \nL 0 0 \nz\n\" style=\"fill:none;\"/>\n  </g>\n  <g id=\"axes_1\">\n   <g id=\"patch_2\">\n    <path d=\"M 43.78125 143.1 \nL 239.08125 143.1 \nL 239.08125 7.2 \nL 43.78125 7.2 \nz\n\" style=\"fill:#ffffff;\"/>\n   </g>\n   <g id=\"matplotlib.axis_1\">\n    <g id=\"xtick_1\">\n     <g id=\"line2d_1\">\n      <defs>\n       <path d=\"M 0 0 \nL 0 3.5 \n\" id=\"me80842b510\" style=\"stroke:#000000;stroke-width:0.8;\"/>\n      </defs>\n      <g>\n       <use style=\"stroke:#000000;stroke-width:0.8;\" x=\"52.658523\" xlink:href=\"#me80842b510\" y=\"143.1\"/>\n      </g>\n     </g>\n     <g id=\"text_1\">\n      <!-- 0 -->\n      <defs>\n       <path d=\"M 31.78125 66.40625 \nQ 24.171875 66.40625 20.328125 58.90625 \nQ 16.5 51.421875 16.5 36.375 \nQ 16.5 21.390625 20.328125 13.890625 \nQ 24.171875 6.390625 31.78125 6.390625 \nQ 39.453125 6.390625 43.28125 13.890625 \nQ 47.125 21.390625 47.125 36.375 \nQ 47.125 51.421875 43.28125 58.90625 \nQ 39.453125 66.40625 31.78125 66.40625 \nz\nM 31.78125 74.21875 \nQ 44.046875 74.21875 50.515625 64.515625 \nQ 56.984375 54.828125 56.984375 36.375 \nQ 56.984375 17.96875 50.515625 8.265625 \nQ 44.046875 -1.421875 31.78125 -1.421875 \nQ 19.53125 -1.421875 13.0625 8.265625 \nQ 6.59375 17.96875 6.59375 36.375 \nQ 6.59375 54.828125 13.0625 64.515625 \nQ 19.53125 74.21875 31.78125 74.21875 \nz\n\" id=\"DejaVuSans-48\"/>\n      </defs>\n      <g transform=\"translate(49.477273 157.698438)scale(0.1 -0.1)\">\n       <use xlink:href=\"#DejaVuSans-48\"/>\n      </g>\n     </g>\n    </g>\n    <g id=\"xtick_2\">\n     <g id=\"line2d_2\">\n      <g>\n       <use style=\"stroke:#000000;stroke-width:0.8;\" x=\"111.840341\" xlink:href=\"#me80842b510\" y=\"143.1\"/>\n      </g>\n     </g>\n     <g id=\"text_2\">\n      <!-- 10 -->\n      <defs>\n       <path d=\"M 12.40625 8.296875 \nL 28.515625 8.296875 \nL 28.515625 63.921875 \nL 10.984375 60.40625 \nL 10.984375 69.390625 \nL 28.421875 72.90625 \nL 38.28125 72.90625 \nL 38.28125 8.296875 \nL 54.390625 8.296875 \nL 54.390625 0 \nL 12.40625 0 \nz\n\" id=\"DejaVuSans-49\"/>\n      </defs>\n      <g transform=\"translate(105.477841 157.698438)scale(0.1 -0.1)\">\n       <use xlink:href=\"#DejaVuSans-49\"/>\n       <use x=\"63.623047\" xlink:href=\"#DejaVuSans-48\"/>\n      </g>\n     </g>\n    </g>\n    <g id=\"xtick_3\">\n     <g id=\"line2d_3\">\n      <g>\n       <use style=\"stroke:#000000;stroke-width:0.8;\" x=\"171.022159\" xlink:href=\"#me80842b510\" y=\"143.1\"/>\n      </g>\n     </g>\n     <g id=\"text_3\">\n      <!-- 20 -->\n      <defs>\n       <path d=\"M 19.1875 8.296875 \nL 53.609375 8.296875 \nL 53.609375 0 \nL 7.328125 0 \nL 7.328125 8.296875 \nQ 12.9375 14.109375 22.625 23.890625 \nQ 32.328125 33.6875 34.8125 36.53125 \nQ 39.546875 41.84375 41.421875 45.53125 \nQ 43.3125 49.21875 43.3125 52.78125 \nQ 43.3125 58.59375 39.234375 62.25 \nQ 35.15625 65.921875 28.609375 65.921875 \nQ 23.96875 65.921875 18.8125 64.3125 \nQ 13.671875 62.703125 7.8125 59.421875 \nL 7.8125 69.390625 \nQ 13.765625 71.78125 18.9375 73 \nQ 24.125 74.21875 28.421875 74.21875 \nQ 39.75 74.21875 46.484375 68.546875 \nQ 53.21875 62.890625 53.21875 53.421875 \nQ 53.21875 48.921875 51.53125 44.890625 \nQ 49.859375 40.875 45.40625 35.40625 \nQ 44.1875 33.984375 37.640625 27.21875 \nQ 31.109375 20.453125 19.1875 8.296875 \nz\n\" id=\"DejaVuSans-50\"/>\n      </defs>\n      <g transform=\"translate(164.659659 157.698438)scale(0.1 -0.1)\">\n       <use xlink:href=\"#DejaVuSans-50\"/>\n       <use x=\"63.623047\" xlink:href=\"#DejaVuSans-48\"/>\n      </g>\n     </g>\n    </g>\n    <g id=\"xtick_4\">\n     <g id=\"line2d_4\">\n      <g>\n       <use style=\"stroke:#000000;stroke-width:0.8;\" x=\"230.203977\" xlink:href=\"#me80842b510\" y=\"143.1\"/>\n      </g>\n     </g>\n     <g id=\"text_4\">\n      <!-- 30 -->\n      <defs>\n       <path d=\"M 40.578125 39.3125 \nQ 47.65625 37.796875 51.625 33 \nQ 55.609375 28.21875 55.609375 21.1875 \nQ 55.609375 10.40625 48.1875 4.484375 \nQ 40.765625 -1.421875 27.09375 -1.421875 \nQ 22.515625 -1.421875 17.65625 -0.515625 \nQ 12.796875 0.390625 7.625 2.203125 \nL 7.625 11.71875 \nQ 11.71875 9.328125 16.59375 8.109375 \nQ 21.484375 6.890625 26.8125 6.890625 \nQ 36.078125 6.890625 40.9375 10.546875 \nQ 45.796875 14.203125 45.796875 21.1875 \nQ 45.796875 27.640625 41.28125 31.265625 \nQ 36.765625 34.90625 28.71875 34.90625 \nL 20.21875 34.90625 \nL 20.21875 43.015625 \nL 29.109375 43.015625 \nQ 36.375 43.015625 40.234375 45.921875 \nQ 44.09375 48.828125 44.09375 54.296875 \nQ 44.09375 59.90625 40.109375 62.90625 \nQ 36.140625 65.921875 28.71875 65.921875 \nQ 24.65625 65.921875 20.015625 65.03125 \nQ 15.375 64.15625 9.8125 62.3125 \nL 9.8125 71.09375 \nQ 15.4375 72.65625 20.34375 73.4375 \nQ 25.25 74.21875 29.59375 74.21875 \nQ 40.828125 74.21875 47.359375 69.109375 \nQ 53.90625 64.015625 53.90625 55.328125 \nQ 53.90625 49.265625 50.4375 45.09375 \nQ 46.96875 40.921875 40.578125 39.3125 \nz\n\" id=\"DejaVuSans-51\"/>\n      </defs>\n      <g transform=\"translate(223.841477 157.698438)scale(0.1 -0.1)\">\n       <use xlink:href=\"#DejaVuSans-51\"/>\n       <use x=\"63.623047\" xlink:href=\"#DejaVuSans-48\"/>\n      </g>\n     </g>\n    </g>\n    <g id=\"text_5\">\n     <!-- epoch -->\n     <defs>\n      <path d=\"M 56.203125 29.59375 \nL 56.203125 25.203125 \nL 14.890625 25.203125 \nQ 15.484375 15.921875 20.484375 11.0625 \nQ 25.484375 6.203125 34.421875 6.203125 \nQ 39.59375 6.203125 44.453125 7.46875 \nQ 49.3125 8.734375 54.109375 11.28125 \nL 54.109375 2.78125 \nQ 49.265625 0.734375 44.1875 -0.34375 \nQ 39.109375 -1.421875 33.890625 -1.421875 \nQ 20.796875 -1.421875 13.15625 6.1875 \nQ 5.515625 13.8125 5.515625 26.8125 \nQ 5.515625 40.234375 12.765625 48.109375 \nQ 20.015625 56 32.328125 56 \nQ 43.359375 56 49.78125 48.890625 \nQ 56.203125 41.796875 56.203125 29.59375 \nz\nM 47.21875 32.234375 \nQ 47.125 39.59375 43.09375 43.984375 \nQ 39.0625 48.390625 32.421875 48.390625 \nQ 24.90625 48.390625 20.390625 44.140625 \nQ 15.875 39.890625 15.1875 32.171875 \nz\n\" id=\"DejaVuSans-101\"/>\n      <path d=\"M 18.109375 8.203125 \nL 18.109375 -20.796875 \nL 9.078125 -20.796875 \nL 9.078125 54.6875 \nL 18.109375 54.6875 \nL 18.109375 46.390625 \nQ 20.953125 51.265625 25.265625 53.625 \nQ 29.59375 56 35.59375 56 \nQ 45.5625 56 51.78125 48.09375 \nQ 58.015625 40.1875 58.015625 27.296875 \nQ 58.015625 14.40625 51.78125 6.484375 \nQ 45.5625 -1.421875 35.59375 -1.421875 \nQ 29.59375 -1.421875 25.265625 0.953125 \nQ 20.953125 3.328125 18.109375 8.203125 \nz\nM 48.6875 27.296875 \nQ 48.6875 37.203125 44.609375 42.84375 \nQ 40.53125 48.484375 33.40625 48.484375 \nQ 26.265625 48.484375 22.1875 42.84375 \nQ 18.109375 37.203125 18.109375 27.296875 \nQ 18.109375 17.390625 22.1875 11.75 \nQ 26.265625 6.109375 33.40625 6.109375 \nQ 40.53125 6.109375 44.609375 11.75 \nQ 48.6875 17.390625 48.6875 27.296875 \nz\n\" id=\"DejaVuSans-112\"/>\n      <path d=\"M 30.609375 48.390625 \nQ 23.390625 48.390625 19.1875 42.75 \nQ 14.984375 37.109375 14.984375 27.296875 \nQ 14.984375 17.484375 19.15625 11.84375 \nQ 23.34375 6.203125 30.609375 6.203125 \nQ 37.796875 6.203125 41.984375 11.859375 \nQ 46.1875 17.53125 46.1875 27.296875 \nQ 46.1875 37.015625 41.984375 42.703125 \nQ 37.796875 48.390625 30.609375 48.390625 \nz\nM 30.609375 56 \nQ 42.328125 56 49.015625 48.375 \nQ 55.71875 40.765625 55.71875 27.296875 \nQ 55.71875 13.875 49.015625 6.21875 \nQ 42.328125 -1.421875 30.609375 -1.421875 \nQ 18.84375 -1.421875 12.171875 6.21875 \nQ 5.515625 13.875 5.515625 27.296875 \nQ 5.515625 40.765625 12.171875 48.375 \nQ 18.84375 56 30.609375 56 \nz\n\" id=\"DejaVuSans-111\"/>\n      <path d=\"M 48.78125 52.59375 \nL 48.78125 44.1875 \nQ 44.96875 46.296875 41.140625 47.34375 \nQ 37.3125 48.390625 33.40625 48.390625 \nQ 24.65625 48.390625 19.8125 42.84375 \nQ 14.984375 37.3125 14.984375 27.296875 \nQ 14.984375 17.28125 19.8125 11.734375 \nQ 24.65625 6.203125 33.40625 6.203125 \nQ 37.3125 6.203125 41.140625 7.25 \nQ 44.96875 8.296875 48.78125 10.40625 \nL 48.78125 2.09375 \nQ 45.015625 0.34375 40.984375 -0.53125 \nQ 36.96875 -1.421875 32.421875 -1.421875 \nQ 20.0625 -1.421875 12.78125 6.34375 \nQ 5.515625 14.109375 5.515625 27.296875 \nQ 5.515625 40.671875 12.859375 48.328125 \nQ 20.21875 56 33.015625 56 \nQ 37.15625 56 41.109375 55.140625 \nQ 45.0625 54.296875 48.78125 52.59375 \nz\n\" id=\"DejaVuSans-99\"/>\n      <path d=\"M 54.890625 33.015625 \nL 54.890625 0 \nL 45.90625 0 \nL 45.90625 32.71875 \nQ 45.90625 40.484375 42.875 44.328125 \nQ 39.84375 48.1875 33.796875 48.1875 \nQ 26.515625 48.1875 22.3125 43.546875 \nQ 18.109375 38.921875 18.109375 30.90625 \nL 18.109375 0 \nL 9.078125 0 \nL 9.078125 75.984375 \nL 18.109375 75.984375 \nL 18.109375 46.1875 \nQ 21.34375 51.125 25.703125 53.5625 \nQ 30.078125 56 35.796875 56 \nQ 45.21875 56 50.046875 50.171875 \nQ 54.890625 44.34375 54.890625 33.015625 \nz\n\" id=\"DejaVuSans-104\"/>\n     </defs>\n     <g transform=\"translate(126.203125 171.376563)scale(0.1 -0.1)\">\n      <use xlink:href=\"#DejaVuSans-101\"/>\n      <use x=\"61.523438\" xlink:href=\"#DejaVuSans-112\"/>\n      <use x=\"125\" xlink:href=\"#DejaVuSans-111\"/>\n      <use x=\"186.181641\" xlink:href=\"#DejaVuSans-99\"/>\n      <use x=\"241.162109\" xlink:href=\"#DejaVuSans-104\"/>\n     </g>\n    </g>\n   </g>\n   <g id=\"matplotlib.axis_2\">\n    <g id=\"ytick_1\">\n     <g id=\"line2d_5\">\n      <defs>\n       <path d=\"M 0 0 \nL -3.5 0 \n\" id=\"m84a5805646\" style=\"stroke:#000000;stroke-width:0.8;\"/>\n      </defs>\n      <g>\n       <use style=\"stroke:#000000;stroke-width:0.8;\" x=\"43.78125\" xlink:href=\"#m84a5805646\" y=\"117.800407\"/>\n      </g>\n     </g>\n     <g id=\"text_6\">\n      <!-- 0.6 -->\n      <defs>\n       <path d=\"M 10.6875 12.40625 \nL 21 12.40625 \nL 21 0 \nL 10.6875 0 \nz\n\" id=\"DejaVuSans-46\"/>\n       <path d=\"M 33.015625 40.375 \nQ 26.375 40.375 22.484375 35.828125 \nQ 18.609375 31.296875 18.609375 23.390625 \nQ 18.609375 15.53125 22.484375 10.953125 \nQ 26.375 6.390625 33.015625 6.390625 \nQ 39.65625 6.390625 43.53125 10.953125 \nQ 47.40625 15.53125 47.40625 23.390625 \nQ 47.40625 31.296875 43.53125 35.828125 \nQ 39.65625 40.375 33.015625 40.375 \nz\nM 52.59375 71.296875 \nL 52.59375 62.3125 \nQ 48.875 64.0625 45.09375 64.984375 \nQ 41.3125 65.921875 37.59375 65.921875 \nQ 27.828125 65.921875 22.671875 59.328125 \nQ 17.53125 52.734375 16.796875 39.40625 \nQ 19.671875 43.65625 24.015625 45.921875 \nQ 28.375 48.1875 33.59375 48.1875 \nQ 44.578125 48.1875 50.953125 41.515625 \nQ 57.328125 34.859375 57.328125 23.390625 \nQ 57.328125 12.15625 50.6875 5.359375 \nQ 44.046875 -1.421875 33.015625 -1.421875 \nQ 20.359375 -1.421875 13.671875 8.265625 \nQ 6.984375 17.96875 6.984375 36.375 \nQ 6.984375 53.65625 15.1875 63.9375 \nQ 23.390625 74.21875 37.203125 74.21875 \nQ 40.921875 74.21875 44.703125 73.484375 \nQ 48.484375 72.75 52.59375 71.296875 \nz\n\" id=\"DejaVuSans-54\"/>\n      </defs>\n      <g transform=\"translate(20.878125 121.599626)scale(0.1 -0.1)\">\n       <use xlink:href=\"#DejaVuSans-48\"/>\n       <use x=\"63.623047\" xlink:href=\"#DejaVuSans-46\"/>\n       <use x=\"95.410156\" xlink:href=\"#DejaVuSans-54\"/>\n      </g>\n     </g>\n    </g>\n    <g id=\"ytick_2\">\n     <g id=\"line2d_6\">\n      <g>\n       <use style=\"stroke:#000000;stroke-width:0.8;\" x=\"43.78125\" xlink:href=\"#m84a5805646\" y=\"84.509643\"/>\n      </g>\n     </g>\n     <g id=\"text_7\">\n      <!-- 0.8 -->\n      <defs>\n       <path d=\"M 31.78125 34.625 \nQ 24.75 34.625 20.71875 30.859375 \nQ 16.703125 27.09375 16.703125 20.515625 \nQ 16.703125 13.921875 20.71875 10.15625 \nQ 24.75 6.390625 31.78125 6.390625 \nQ 38.8125 6.390625 42.859375 10.171875 \nQ 46.921875 13.96875 46.921875 20.515625 \nQ 46.921875 27.09375 42.890625 30.859375 \nQ 38.875 34.625 31.78125 34.625 \nz\nM 21.921875 38.8125 \nQ 15.578125 40.375 12.03125 44.71875 \nQ 8.5 49.078125 8.5 55.328125 \nQ 8.5 64.0625 14.71875 69.140625 \nQ 20.953125 74.21875 31.78125 74.21875 \nQ 42.671875 74.21875 48.875 69.140625 \nQ 55.078125 64.0625 55.078125 55.328125 \nQ 55.078125 49.078125 51.53125 44.71875 \nQ 48 40.375 41.703125 38.8125 \nQ 48.828125 37.15625 52.796875 32.3125 \nQ 56.78125 27.484375 56.78125 20.515625 \nQ 56.78125 9.90625 50.3125 4.234375 \nQ 43.84375 -1.421875 31.78125 -1.421875 \nQ 19.734375 -1.421875 13.25 4.234375 \nQ 6.78125 9.90625 6.78125 20.515625 \nQ 6.78125 27.484375 10.78125 32.3125 \nQ 14.796875 37.15625 21.921875 38.8125 \nz\nM 18.3125 54.390625 \nQ 18.3125 48.734375 21.84375 45.5625 \nQ 25.390625 42.390625 31.78125 42.390625 \nQ 38.140625 42.390625 41.71875 45.5625 \nQ 45.3125 48.734375 45.3125 54.390625 \nQ 45.3125 60.0625 41.71875 63.234375 \nQ 38.140625 66.40625 31.78125 66.40625 \nQ 25.390625 66.40625 21.84375 63.234375 \nQ 18.3125 60.0625 18.3125 54.390625 \nz\n\" id=\"DejaVuSans-56\"/>\n      </defs>\n      <g transform=\"translate(20.878125 88.308862)scale(0.1 -0.1)\">\n       <use xlink:href=\"#DejaVuSans-48\"/>\n       <use x=\"63.623047\" xlink:href=\"#DejaVuSans-46\"/>\n       <use x=\"95.410156\" xlink:href=\"#DejaVuSans-56\"/>\n      </g>\n     </g>\n    </g>\n    <g id=\"ytick_3\">\n     <g id=\"line2d_7\">\n      <g>\n       <use style=\"stroke:#000000;stroke-width:0.8;\" x=\"43.78125\" xlink:href=\"#m84a5805646\" y=\"51.21888\"/>\n      </g>\n     </g>\n     <g id=\"text_8\">\n      <!-- 1.0 -->\n      <g transform=\"translate(20.878125 55.018098)scale(0.1 -0.1)\">\n       <use xlink:href=\"#DejaVuSans-49\"/>\n       <use x=\"63.623047\" xlink:href=\"#DejaVuSans-46\"/>\n       <use x=\"95.410156\" xlink:href=\"#DejaVuSans-48\"/>\n      </g>\n     </g>\n    </g>\n    <g id=\"ytick_4\">\n     <g id=\"line2d_8\">\n      <g>\n       <use style=\"stroke:#000000;stroke-width:0.8;\" x=\"43.78125\" xlink:href=\"#m84a5805646\" y=\"17.928116\"/>\n      </g>\n     </g>\n     <g id=\"text_9\">\n      <!-- 1.2 -->\n      <g transform=\"translate(20.878125 21.727335)scale(0.1 -0.1)\">\n       <use xlink:href=\"#DejaVuSans-49\"/>\n       <use x=\"63.623047\" xlink:href=\"#DejaVuSans-46\"/>\n       <use x=\"95.410156\" xlink:href=\"#DejaVuSans-50\"/>\n      </g>\n     </g>\n    </g>\n    <g id=\"text_10\">\n     <!-- loss -->\n     <defs>\n      <path d=\"M 9.421875 75.984375 \nL 18.40625 75.984375 \nL 18.40625 0 \nL 9.421875 0 \nz\n\" id=\"DejaVuSans-108\"/>\n      <path d=\"M 44.28125 53.078125 \nL 44.28125 44.578125 \nQ 40.484375 46.53125 36.375 47.5 \nQ 32.28125 48.484375 27.875 48.484375 \nQ 21.1875 48.484375 17.84375 46.4375 \nQ 14.5 44.390625 14.5 40.28125 \nQ 14.5 37.15625 16.890625 35.375 \nQ 19.28125 33.59375 26.515625 31.984375 \nL 29.59375 31.296875 \nQ 39.15625 29.25 43.1875 25.515625 \nQ 47.21875 21.78125 47.21875 15.09375 \nQ 47.21875 7.46875 41.1875 3.015625 \nQ 35.15625 -1.421875 24.609375 -1.421875 \nQ 20.21875 -1.421875 15.453125 -0.5625 \nQ 10.6875 0.296875 5.421875 2 \nL 5.421875 11.28125 \nQ 10.40625 8.6875 15.234375 7.390625 \nQ 20.0625 6.109375 24.8125 6.109375 \nQ 31.15625 6.109375 34.5625 8.28125 \nQ 37.984375 10.453125 37.984375 14.40625 \nQ 37.984375 18.0625 35.515625 20.015625 \nQ 33.0625 21.96875 24.703125 23.78125 \nL 21.578125 24.515625 \nQ 13.234375 26.265625 9.515625 29.90625 \nQ 5.8125 33.546875 5.8125 39.890625 \nQ 5.8125 47.609375 11.28125 51.796875 \nQ 16.75 56 26.8125 56 \nQ 31.78125 56 36.171875 55.265625 \nQ 40.578125 54.546875 44.28125 53.078125 \nz\n\" id=\"DejaVuSans-115\"/>\n     </defs>\n     <g transform=\"translate(14.798437 84.807812)rotate(-90)scale(0.1 -0.1)\">\n      <use xlink:href=\"#DejaVuSans-108\"/>\n      <use x=\"27.783203\" xlink:href=\"#DejaVuSans-111\"/>\n      <use x=\"88.964844\" xlink:href=\"#DejaVuSans-115\"/>\n      <use x=\"141.064453\" xlink:href=\"#DejaVuSans-115\"/>\n     </g>\n    </g>\n   </g>\n   <g id=\"line2d_9\">\n    <path clip-path=\"url(#pdaf7ca31c1)\" d=\"M 52.658523 13.377273 \nL 58.78078 119.82954 \nL 64.903037 130.743872 \nL 71.025294 134.053375 \nL 77.147551 135.420079 \nL 83.269808 136.058944 \nL 89.392065 136.381515 \nL 95.514322 136.555152 \nL 101.636579 136.654492 \nL 107.758836 136.714952 \nL 113.881093 136.754162 \nL 120.00335 136.781275 \nL 126.125607 136.801216 \nL 132.247864 136.816722 \nL 138.370121 136.829368 \nL 144.492379 136.84008 \nL 150.614636 136.849429 \nL 156.736893 136.857778 \nL 162.85915 136.865351 \nL 168.981407 136.872314 \nL 175.103664 136.878771 \nL 181.225921 136.884801 \nL 187.348178 136.890466 \nL 193.470435 136.895806 \nL 199.592692 136.900861 \nL 205.714949 136.905664 \nL 211.837206 136.910231 \nL 217.959463 136.914587 \nL 224.08172 136.918745 \nL 230.203977 136.922727 \n\" style=\"fill:none;stroke:#1f77b4;stroke-linecap:square;stroke-width:1.5;\"/>\n   </g>\n   <g id=\"patch_3\">\n    <path d=\"M 43.78125 143.1 \nL 43.78125 7.2 \n\" style=\"fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;\"/>\n   </g>\n   <g id=\"patch_4\">\n    <path d=\"M 239.08125 143.1 \nL 239.08125 7.2 \n\" style=\"fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;\"/>\n   </g>\n   <g id=\"patch_5\">\n    <path d=\"M 43.78125 143.1 \nL 239.08125 143.1 \n\" style=\"fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;\"/>\n   </g>\n   <g id=\"patch_6\">\n    <path d=\"M 43.78125 7.2 \nL 239.08125 7.2 \n\" style=\"fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;\"/>\n   </g>\n  </g>\n </g>\n <defs>\n  <clipPath id=\"pdaf7ca31c1\">\n   <rect height=\"135.9\" width=\"195.3\" x=\"43.78125\" y=\"7.2\"/>\n  </clipPath>\n </defs>\n</svg>\n"
          },
          "metadata": {
            "tags": []
          }
        },
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "<tensorflow.python.keras.callbacks.History at 0x7f40c8330978>"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 20
        }
      ]
    }
  ]
}